package com.pubinfo.passbook.common.entity;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.pubinfo.passbook.common.model.dto.financial.Result;
import com.pubinfo.passbook.common.utils.XmlTool;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 财政电子票据实体类
 *
 * @TableName t_source_passbook
 */
@Slf4j
@Data
@NoArgsConstructor
@TableName(value = "t_source_passbook", autoResultMap = true)
@ApiModel(value = "TPassbook", description = "票据")
public class TPassbook extends Model implements Serializable {
  /**
   * 票据标识(票据 ID)
   */
  //@TableId(type = IdType.ASSIGN_UUID, value = "id")
  // @ApiModelProperty("发票id")
  //private String id;
  @TableId(type = IdType.ASSIGN_UUID, value = "id")
  private String id;

  @ApiModelProperty("票据id(源数据id)")
  @JSONField(name = "einvoiceId")
  private String eInvoiceId;
  @ApiModelProperty("人员id")
  private String persionId;

  private BigDecimal reimbursableSum = BigDecimal.ZERO;
  /**
   * 票据种类编码
   */
  @ApiModelProperty("票据种类编码")
  private String classCode;
  
  /**
   * 开票时间，格式 HHmmss
   */
  @ApiModelProperty("开票时间，格式 HHmmss")
  private String issueTime;
  
  /**
   * 票据种类名称
   */
  @ApiModelProperty("票据种类名称")
  private String className;
  
  /**
   * 电子票据代码
   */
  @ApiModelProperty("电子票据代码")
  private String einvoiceCode;
  
  /**
   * 换开状态 0 未换开 1 已换开
   */
  @ApiModelProperty("换开状态 0 未换开 1 已换开")
  private Integer switchStatus;
  
  /**
   * 金额
   */
  @ApiModelProperty("金额")
  @JsonFormat(shape = JsonFormat.Shape.STRING)
  private BigDecimal totalAmount;
  
  /**
   * 开票单位代码
   */
  @ApiModelProperty("开票单位代码")
  private String invoicingPartyCode;
  
  /**
   * 交款人名称
   */
  @ApiModelProperty("交款人名称")
  private String payerPartyName;
  
  @TableField(typeHandler = FastjsonTypeHandler.class)
  private JSONObject dataJson;
  /**
   * 缴款人代码
   */
  @ApiModelProperty("缴款人代码")
  private String payerPartyCode;
  
  /**
   * 开票单位名称
   */
  @ApiModelProperty("开票单位名称")
  private String invoicingPartyName;
  
  /**
   * 电子票据校验码
   */
  @ApiModelProperty("电子票据校验码")
  private String randomNumber;
  
  /**
   * 电子票据号码
   */
  @ApiModelProperty("电子票据号码")
  private String einvoiceNumber;
  
  @ApiModelProperty("单据表id")
  private String artificialId;
  
  /**
   * 开票日期，格式 YYYYMMdd
   */
  @ApiModelProperty("开票日期，格式 YYYYMMdd")
  private String issueDate;
  
  /**
   * 票据状态 0 冲红 1 正常
   */
  @ApiModelProperty("票据状态 0 冲红 1 正常 2 作废票")
  private Integer invoiceStatus;
  
  /**
   * 电子票据代码名称
   */
  @ApiModelProperty("电子票据代码名称")
  private String einvoiceName;
  
  @ApiModelProperty("所属公司")
  private String nsrsbh;
  /**
   * 是否锁定 0锁定,1解锁 下载过来默认就锁定.
   */
  @ApiModelProperty("票据是否被系统锁定 N 未锁定，Y 锁定 此锁定与票据详情里面的锁定不一样")
  private String systemIsLocked = "N";
  /**
   * 创建时间
   */
  @ApiModelProperty("创建时间")
  @TableField(fill = FieldFill.INSERT)
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  private Date createTime;
  
  @ApiModelProperty("修改时间")
  @TableField(fill = FieldFill.UPDATE)
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  private Date updateTime;
  @ApiModelProperty(value = "交款人类型 1 个人 2 单位")
  private String payerPartyType;
  @ApiModelProperty(value = "锁定原因")
  private String lockedReason;
  @ApiModelProperty(value = "锁定日期")
  private String lockedDate;
  @ApiModelProperty(value = "锁定机构名称")
  private String lockCorpName;
  @ApiModelProperty(value = "票据 pdf 详情")
  private String detailPdf;
  @ApiModelProperty(value = "票据 XML 详情")
  private String einvoiceXml;
  @ApiModelProperty(value = "票据 PDF 地址")
  @JSONField(name = "einvoicePDF")
  private String einvoicePdf;
  @ApiModelProperty(value = "票据种类")
  private String einvoiceType;

  @ApiModelProperty(value = "冲红时不为空，源票据代码")
  private String relatedInvoiceCode;

  @ApiModelProperty(value = "冲红时不为空，源票据号码")
  private String relatedInvoiceNumber;
  @ApiModelProperty(value = "pdf是否下载成功 1成功 0未成功")
  private boolean isDownload;
  
  @ApiModelProperty(value = "同步任务日志id")
  private String logId;
  
  @TableField(exist = false)
  @ApiModelProperty(value = "报销记录")
  private List<TSourcePassbookReimburse> reimburseList;
  
  public boolean getIsDownload() {
    return isDownload;
  }
  
  public void setAllResult(Result result) {
    setResult(result);
    this.eInvoiceId = result.getEinvoiceId();
    this.randomNumber = result.getRandomNumber();
    this.totalAmount = new BigDecimal(result.getTotalAmount());
    this.issueDate = result.getIssueDate();
    this.invoicingPartyName = result.getInvoicingPartyName();
    this.payerPartyName = result.getPayerPartyName();
    //this.isLocked = result.getIsLocked();
    this.switchStatus = Integer.valueOf(result.getSwitchStatus());
    this.einvoiceCode = result.getEinvoiceCode();
    this.einvoiceNumber = result.getEinvoiceNumber();
    //取id 中间字段就是class Code
    this.classCode = result.getEinvoiceId().split("_").length>=3 ? result.getEinvoiceId().split("_")[2]:null;
    Document document = null;
    String xmlStr = result.getEinvoiceXML();
    if (XmlTool.isXmlDocument(xmlStr)) {
      try {
        document = DocumentHelper.parseText(xmlStr);
      } catch (DocumentException e) {
        log.error("解析票据数据失败", e);
      }
      Element element = document.getRootElement().element("EInvoiceData");
      if (element != null) {
        Element elementMain = element.element("Main");
        Element payerPartyCode = elementMain.element("PayerParty").element("PayerPartyCode");
        //this.dataJson = jsonObject;
        Element invoicingParty = elementMain.element("InvoicingParty");
        Element invoicingPartyCode = invoicingParty.element("PayerPartyCode");
        Element invoicingPartyName = invoicingParty.element("InvoicingPartyName");
  
        Element issueDate = elementMain.element("IssueDate");
        Element issueTime = elementMain.element("IssueTime");
        if (issueTime != null) {
          this.issueTime = issueTime.getText().replaceAll(":", "").trim().replaceAll("\"", "");
        }
        Element eInvoiceName = elementMain.element("EInvoiceName");
        if (eInvoiceName != null) {
          this.einvoiceName = eInvoiceName.getText().replaceAll("\"", "");
        }
        if (payerPartyCode != null) {
          this.payerPartyCode = payerPartyCode.getText().replaceAll("\"", "");
        }
        if (StringUtils.isBlank(this.issueDate)) {
          this.issueDate = issueDate.getText().replaceAll(":", "").trim().replaceAll("\"", "");
        }
        if (invoicingPartyCode != null) {
          this.invoicingPartyCode = invoicingPartyCode.getText().replaceAll("\"", "");
        }
        if (invoicingPartyName != null) {
          this.invoicingPartyName = invoicingPartyName.getText().replaceAll("\"", "");
        }
  
      }
  
    }
  
  }
  
  //  public static void main(String[] args) {
//    String str ="17:13:36";
//    System.out.println(str.replaceAll(":",""));
//  }
  public void setResult(Result result) {
  
    //从xml里面取
    Document document = null;
    String xmlStr = result.getEinvoiceXML();
    this.invoiceStatus = 1;//默认设置正常
    if (StringUtils.isNotBlank(xmlStr) && XmlTool.isXmlDocument(xmlStr)) {
      try {
        document = DocumentHelper.parseText(xmlStr);
      } catch (DocumentException e) {
        log.error("解析票据数据失败", e);
      }
      Element element = document.getRootElement().element("EInvoiceData");
      if (element != null) {
        Element main = element.element("Main");
        Element payerParty = main.element("PayerParty");
        Element payerPartyType = payerParty.element("PayerPartyType");
        if (StringUtils.isNotBlank(result.getPayerPartyType())) {
          this.payerPartyType = result.getPayerPartyType();
        } else if (payerPartyType != null) {
          this.payerPartyType = payerPartyType.getText().replaceAll("\"", "");
        }
        //如果冲红的源票据不为空，则设置
        Element mainExt = main.element("MainExt");
        if (mainExt != null) {
          Element relatedInvoiceCode = mainExt.element("RelatedInvoiceCode");
          Element relatedInvoiceNumber = mainExt.element("RelatedInvoiceNumber");
          if (relatedInvoiceCode != null && StringUtils.isNotBlank(relatedInvoiceCode.getText())) {
            this.invoiceStatus = 0;
            this.relatedInvoiceCode = relatedInvoiceCode.getText().replaceAll("\"", "");
          }
          if (relatedInvoiceNumber != null && StringUtils.isNotBlank(relatedInvoiceNumber.getText())) {
            this.invoiceStatus = 0;
            this.relatedInvoiceNumber = relatedInvoiceNumber.getText().replaceAll("\"", "");
          }
          //获取竖版票据状态，如果不为空，则设置
          Element medicalEInvoice = mainExt.element("MedicalEInvoice");
          if (medicalEInvoice != null && medicalEInvoice.element("EinvoiceStatus") != null) {
            Integer einvoiceStatus = Integer.valueOf(medicalEInvoice.element("EinvoiceStatus").getText().replaceAll("\"", ""));
            this.invoiceStatus = einvoiceStatus;
          }
        }
      }
    
    }
  
    this.lockedReason = result.getLockedReason();
    this.lockedDate = result.getLockedDate();
    this.lockCorpName = result.getLockCorpName();
    this.detailPdf = result.getDetailPDF();
    this.einvoiceXml = result.getEinvoiceXML();
    this.einvoicePdf = result.getEinvoicePDF();
    this.einvoiceType = result.getEinvoiceType();
    List<TSourcePassbookReimburse> reimburses = result.getReimburseList();
    if (!CollectionUtils.isEmpty(reimburses)) {
      reimburses.stream().forEach(tReimburse -> {
        tReimburse.setEInvoiceId(result.getEinvoiceId());
      });
    }
    this.reimburseList = reimburses;
  }
  
  public TPassbook(String id,String reimbursableSum) {
    this.id=id;
    this.reimbursableSum=new BigDecimal(reimbursableSum);
  }

}